package plaintextmachine

import (
	"fmt"
	"http"
	"utf8"
)

var editorHeader = "<!DOCTYPE html>\n" +
		"<html><head><title>The Plain Text Machine</title>" +
		"<style>body { " +
			"font-family: Andale Mono, Courier New, Courier, monospace; " +
			"margin-right: 10%; " +
			"margin-left: 10%; " +
			"margin-top: 2em; " +
			"line-height: 130%; " +
		"}" +
		"textarea {" +
			"font-family: Andale Mono, Courier New, Courier, monospace; " +
		"}" +
		"</style>"

var textHeader = "<!DOCTYPE html>\n" +
		"<html><head>" +
		"<style>body { " +
			"font-family: Andale Mono, Courier New, Courier, monospace; " +
			"margin-right: 10%; " +
			"margin-left: 10%; " +
			"margin-top: 2em; " +
			"line-height: 130%; " +
		"}" +
		"</style>"

var script = "<script>" +
		"function generate() {" +
			"var input = document.getElementById('message');" +
			"var output = document.getElementById('link');" +
			"var escaped = " +
				"encodeURIComponent(input.value).replace(/%20/g, '+');" +
			"if (escaped.length > 2000) {" +
				"output.innerHTML = 'Message is too long by ' + " +
					"(escaped.length - 2000) + ' characters.'" +
			"} else {" +
				"output.innerHTML = '<a href=\"/show?msg=' + " +
					"escaped +'\">Show Your Message</a>';" +
			"}" +
		"}" +
		"</script>"

var middle = "</head><body>"

var form = "<h1>The Plain Text Machine</h1>Enter your message:<br>" +
		"<textarea id=\"message\" cols=\"80\" rows=\"20\"></textarea><br>" +
		"<button onclick=\"generate()\">Generate Link</button><br>" +
		"<div id=\"link\"></div>"

var footer = "</body></html>"

func PrintHtml(text *utf8.String, out http.ResponseWriter) {
	spaces := false
	
	fmt.Fprint(out, textHeader, middle)
	for i := 0; i < text.RuneCount(); i++ {
		currentChar := text.At(i)
	
		if currentChar == 32 && !spaces {
			// A first space.
			fmt.Fprint(out, " ")
			spaces = true
		} else {
			if currentChar == 32 {
				// Space following another space
				fmt.Fprint(out, "&nbsp;")
			} else if currentChar == 10 {
				// Newline
				fmt.Fprint(out, "<br>")
			} else if currentChar == 9 {
				// Tab
				fmt.Fprint(out, "&nbsp;&nbsp;&nbsp; ")
			} else if currentChar == 38 {
				// &
				fmt.Fprint(out, "&amp;")
			} else if currentChar == 60 {
				// <
				fmt.Fprint(out, "&lt;")
			} else if currentChar == 62 {
				// >
				fmt.Fprint(out, "&gt;")
			} else if currentChar < 31 || currentChar == 128 {
				// Skip control characters.
			} else if currentChar < 127 {
				fmt.Fprintf(out, "%c", currentChar)
			} else {
				fmt.Fprintf(out, "&#%d;", text.At(i))
			}
			spaces = false
		}
	}
	fmt.Fprint(out, footer)
}

func show(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	// Get the message from the URL.
	PrintHtml(utf8.NewString(r.FormValue("msg")), w)
}

func handle(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprint(w, editorHeader, script, middle, form, footer)
}

func init() {
	http.HandleFunc("/", handle)
	http.HandleFunc("/show", show)
}
